package de.openlaboratory.elib.controller.servlets;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import de.openlaboratory.elib.controller.ElibService;
import de.openlaboratory.elib.core.ComponentRegistry;
import de.openlaboratory.elib.core.LogManager;
import de.openlaboratory.elib.model.library.Library;
import de.openlaboratory.elib.utilities.OpenLabUtilities;

public class LibraryServlet extends GenericDataServlet
{
	private static final String SERVLET_DESCRIPTION = "Library Functionalities";
	private static final String LIST_LIBRARIES = "/WEB-INF/eLibListLibraries.jsp";
	private static final String EDIT_LIBRARY = "/WEB-INF/eLibEditLibrary.jsp";

	private static final long serialVersionUID = 6084354422036503860L;

	private Map<String, String> messages;
	
	@Override
	protected void processRequest(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException
	{
		messages = new HashMap<String, String>();
		request.setAttribute("messages", messages);

		String action = (String) request.getParameter("elib_action");
		String elibNamespace = (String) request.getParameter("elib_ns");
		String elibDocBase = (String) request.getParameter("elib_docbase");
		
		Library newLib = getLibraryFromServletRequest(request);

		String page = null;

		if (action == null)
		{
			action = "unknown";
		}

		switch (action.toUpperCase())
		{
//			case "LISTALL":
//				page = listLibraries(request);
//				break;
			case "CREATE":
				page = createLibrary(request, newLib);
				break;
			case "READ":
				messages.clear();
				page = readLibrary(request, newLib.getId());
				break;
			case "EDIT":
				page = editLibrary(request, newLib);
				break;
			case "DELETE":
				page = deleteLibrary(request, newLib.getId());
				break;
			default:
				page = listLibraries(request);
				break;
		}

		RequestDispatcher view = request.getRequestDispatcher(page);
		view.forward(request, response);
	}

	private Library getLibraryFromServletRequest(HttpServletRequest request)
	{
		Long id = OpenLabUtilities.stringToLong(request.getParameter("id"));
		String name = request.getParameter("name");
		String description = request.getParameter("description");
		int key = OpenLabUtilities.stringToInt(request.getParameter("key"));

		if ((name == null || name.trim().isEmpty()))
		{
			messages.put("name", "Please enter Library name");
		}

		if ((name != null) && (!name.matches("\\p{Alnum}+")))
		{
			messages.put("name", "Please enter alphanumeric characters only");
		}

		if (key <= 0)
		{
			messages.put("key", "Please enter digits only");
		}
		
		return new Library(id, name, description, key);
	}

	private String createLibrary(HttpServletRequest request, Library newLib)
	{
		if (messages.isEmpty())
		{
			// create new entry
			LogManager.logMessage("Creating new Library");
			ElibService service = ComponentRegistry.lookupService(Library.class, "CREATE");
			Library library = (Library) service.execute("CREATE", newLib).get(0);

			messages.put("success", String.format("Success: Library [%s: %s] saved.", newLib.getName(), newLib.getDescription()));
			
			return listLibraries(request);
		}
		else
		{
			newLib = new Library();
			LogManager.logMessage("No parameters set. Display empty form.");
		}

		
		request.setAttribute("param", newLib);
		request.setAttribute("elib_action", "CREATE");
		
		return EDIT_LIBRARY;
	}

	private String readLibrary(HttpServletRequest request, Long id)
	{
		ElibService service = ComponentRegistry.lookupService(Library.class, "READ");
		Library library = (Library) service.execute("READ", id).get(0);
		
		request.setAttribute("param", library);
		request.setAttribute("elib_action", "EDIT");

		return EDIT_LIBRARY;
	}

	private String listLibraries(HttpServletRequest request)
	{
		ElibService service = ComponentRegistry.lookupService(Library.class, "LISTALL");
		List<Library> libraries = (List<Library>) service.execute("LISTALL", null);

		request.setAttribute("libraries", libraries);

		return LIST_LIBRARIES;
	}

	private String editLibrary(HttpServletRequest request, Library newLib)
	{
		if (newLib != null && newLib.getId() > 0)
		{
			LogManager.logMessage("Updating Library ID: " + newLib.getId());

			Library library = null;
			
			if (messages.isEmpty())
			{
				ElibService service = ComponentRegistry.lookupService(Library.class, "UPDATE");
				library = (Library) service.execute("UPDATE", newLib).get(0);
			}
			else
			{
				LogManager.logMessage("Error messages exist.");
			}
			
			if (library != null)
			{
				LogManager.logMessage("Loaded Library '" + library.getName() + "' " + library.getId()+ ". key: " + library.getNumericKey());
				request.setAttribute("param", library);

				return listLibraries(request);
			}
			else
			{
				LogManager.logMessage("Library could not be loaded");
				readLibrary(request, newLib.getId());
			}
		}
		
		request.setAttribute("elib_action", "EDIT");

		return EDIT_LIBRARY;
	}


	private String deleteLibrary(HttpServletRequest request, Long id)
	{
		ElibService service = ComponentRegistry.lookupService(Library.class, "DELETE");
		service.execute("DELETE", id);
		
		return listLibraries(request);
	}

	/**
	 * Returns a short description of the servlet.
	 * 
	 * @return a String containing servlet description
	 */
	@Override
	public String getServletInfo()
	{
		return SERVLET_DESCRIPTION;
	}
}
